package cn.iktz.mather.know.renwen_lishi;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.iktz.mather.know.common.TrieTreeBuilder;
import cn.iktz.mather.know.web.beans.NameValue;
import cn.iktz.mather.know.web.config.ElasticConfig;
import cn.iktz.mather.know.web.utils.Base64Util;
import cn.iktz.mather.know.web.utils.GZipUtils;
import cn.iktz.mather.know.web.utils.ResultUtils;
import net.sf.json.JSONObject;

@Controller
public class RenwenLishiController {

	@Autowired
	ElasticConfig elasticConfig;

	@Autowired
	private Client client;

	@RequestMapping(value = "/{id}")
	public String detail(@PathVariable("id") String id, HttpServletRequest request) {
		SearchRequestBuilder sqb = build();
		sqb.setQuery(QueryBuilders.termQuery("md5", id));

		SearchResponse response = sqb.execute().actionGet();
		JSONObject resultJson = null;
		if (response.getHits().getTotalHits() == 1) {
			SearchHit term = response.getHits().getAt(0);
			String sourceAsString = term.getSourceAsString();

			JSONObject jsonObject = JSONObject.fromObject(sourceAsString);
			String html = jsonObject.getString("article_html");
			try {
				byte[] decode = Base64Util.decode(html);
				String data = new String(GZipUtils.decompress(decode));
				jsonObject.remove("article_html");
				jsonObject.accumulate("article_html", data);
			} catch (Exception e) {
				e.printStackTrace();
			}
			resultJson = jsonObject;
		}
		request.setAttribute("data", resultJson);
		return "world/history_detail";
	}

	@RequestMapping(value = "/suggest/{keyword}")
	@ResponseBody
	public Map<String, Object> suggest(@PathVariable("keyword") String keyword) {
		List<String> suggest = TrieTreeBuilder.suggest(keyword);
		System.out.println(keyword);
		if (suggest != null && suggest.size() > 10) {
			suggest = suggest.subList(0, 8);
		}

		return ResultUtils.add(new NameValue("data", suggest));
	}

	@RequestMapping(value = "/h/{p}")
	public String index(@PathVariable("p") Integer p, HttpServletRequest request) {
		SearchRequestBuilder sqb = build();
		MatchAllQueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();

		sqb.setQuery(matchAllQuery);
		sqb.setFrom(p * 10 + 1).setSize(10);
		SearchResponse response = sqb.execute().actionGet();

		SearchHits hits = response.getHits();
		List<JSONObject> data = new ArrayList<>();

		JSONObject pageBean = new JSONObject();
		long totalHits = hits.totalHits();
		pageBean.accumulate("total", totalHits);
		pageBean.accumulate("current", p);
		pageBean.accumulate("totalSize", (int) (totalHits / 10));

		for (SearchHit searchHit : hits) {
			try {
				String sourceAsString = searchHit.getSourceAsString();
				JSONObject object = JSONObject.fromObject(sourceAsString);

				String html = object.getString("article_html");
				byte[] decode = Base64Util.decode(html);

				Document doc = Jsoup.parse(new String(GZipUtils.decompress(decode)));
				Elements select = doc.select("p");

				Element e = new Element("<br/>");

				int count = 0;
				for (int i = 1; i < select.size(); i++) {
					Element element3 = select.get(i);
					Elements select2 = element3.select("img");
					if (select2.size() == 0 && count < 2 && element3.text().length() > 100
							&& element3.text().length() < 200) {

						e.append(element3.html()).append("<p><p/>");
						count++;
					}
				}

				object.remove("article_html");
				object.accumulate("html", e.html().toString());
				if (count > 1) {
					data.add(object);
				}

			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		request.setAttribute("pageBean", pageBean);
		request.setAttribute("data", data);

		return "world/history_index";
	}

	@RequestMapping(value = "/h/s")
	public String search(String w, Integer p, HttpServletRequest request) {
		request.setAttribute("keyword", w);
		SearchRequestBuilder sqb = build();
		BoolQueryBuilder bqb = new BoolQueryBuilder();
		bqb.should(QueryBuilders.matchQuery("title", w));
		sqb.addHighlightedField("title");

		sqb.setHighlighterPreTags("<span style=\"color:red\">");
		sqb.setHighlighterPostTags("</span>");

		sqb.setQuery(bqb);
		p = (p == null ? 1 : p);
		sqb.setFrom((p - 1) * 10 + 1).setSize(10);
		SearchResponse response = sqb.execute().actionGet();

		SearchHits hits = response.getHits();
		List<JSONObject> data = new ArrayList<>();

		JSONObject pageBean = new JSONObject();
		long totalHits = hits.totalHits();
		pageBean.accumulate("total", totalHits);
		pageBean.accumulate("current", p);
		pageBean.accumulate("totalSize", (int) (totalHits / 10));

		for (SearchHit searchHit : hits) {
			try {
				String sourceAsString = searchHit.getSourceAsString();
				Text text = searchHit.getHighlightFields().get("title").fragments()[0];

				JSONObject object = JSONObject.fromObject(sourceAsString);
				object.remove("title");
				object.accumulate("title", text.toString());

				String html = object.getString("article_html");
				byte[] decode = Base64Util.decode(html);

				Document doc = Jsoup.parse(new String(GZipUtils.decompress(decode)));
				Elements select = doc.select("p");

				Element e = new Element("<br/>");

				int count = 0;
				for (int i = 1; i < select.size(); i++) {
					Element element3 = select.get(i);
					Elements select2 = element3.select("img");
					if (select2.size() == 0 && count < 2 && element3.text().length() > 100
							&& element3.text().length() < 200) {

						e.append(element3.html()).append("<p><p/>");
						count++;
					}
				}

				object.remove("article_html");
				object.accumulate("html", e.html().toString());
				if (count > 1) {
					data.add(object);
				}

			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		request.setAttribute("pageBean", pageBean);
		request.setAttribute("data", data);

		return "world/history_search_result";
	}

	@RequestMapping(value = "/h/so")
	public String search() {
		return "world/history_search_index";
	}

	@RequestMapping(value = "/")
	public void index(HttpServletRequest req, HttpServletResponse res) {
		try {
			req.getRequestDispatcher("/h/1").forward(req, res);
		} catch (ServletException | IOException e) {
			e.printStackTrace();
		}
	}

	public SearchRequestBuilder build() {
		SearchRequestBuilder searchRequestBuilder = client.prepareSearch(elasticConfig.getElasticsearch_index())
				.setTypes(elasticConfig.getElasticsearch_type()).setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
		return searchRequestBuilder;
	}
}
